
____________________________________________________________________________________________

;;
  Used Macros Strings Variables:
  
    &1, &2, &3              Proc
    &9, &10 to &19          For
 
  Used Macros Counters Variables:
 
    &&0, &&1                If
    &&2, &&3                While
    &&4, &&5                Do
    &&6, &&7                For
    
  Local Labels Attributions:
  
    O1                      On
    P9                      Proc
    I0,... I9, J0,... J9    If
    W0,... W9               While
    D0,... D9               Do
    F0,... F9               For
;;
____________________________________________________________________________________________

[= e   < b    > a    <s l    >s g    =< be    <= be    => ae    >= ae    <> ne]
____________________________________________________________________________________________

; Multi push, pop, mov, move, inc, and dec  Macros:

[push | push #1 | #+1]
[pop | pop #1 | #+1]
[mov | mov #1 #2 | #+2]
[move | push #2 | pop #1 | #+2]
[inc | inc #1 | #+1]
[dec | dec #1 | #+1]
____________________________________________________________________________________________

[Exchange | push #1 | push #2 | pop #1 | pop #2 | #+2]
____________________________________________________________________________________________

[On | cmp #1 #3 | jn#2 O1> | #4>L | O1:]
____________________________________________________________________________________________

[call | #If #1=str
            ApiPush #L>2
        #Else
            push #L>2
        #End_If
        call #1]

[ApiPush | #If #1=str
                push {#1, 0}
           #Else
                push #1
           #End_If
           #+1]
____________________________________________________________________________________________

; C calling convention:

[ccall
    push #L>2 | call #1
    #If #N>1
        add esp ((#N-1)*4)
    #EndIf]
____________________________________________________________________________________________

[.If
    #If &&0<>0
        #If &&0<> '0'
            #Error 'Unpaired If'
        #End_If
    #End_If
    &&0= '0' | &&1=Pos
    AndCmp I&&0>>, #1>L]

[.End_If | I&&0: | J&&0:
    #If &&0<> '0'
        #ErrorPos &&1 'Unpaired If'
    #End_If
    &&0=0]

[If
    #If &&0=0
        &&0= '0'
    #Else
        &&0=&&0+1
    #End_If

    AndCmp I&&0>>, #1>L]

[Else_If | jmp J&&0>> | I&&0:
    AndCmp I&&0>>, #1>L]

[Else | jmp J&&0>> | I&&0: ]

[End_If | I&&0: | J&&0:
    #If &&0= '0'
        &&0=0
    #Else
        &&0=&&0-1
    #End_If]

[AndCmp | cmp #2 #4 | jn#3 #F | #+3]
____________________________________________________________________________________________

[.While
    #If &&2<>0
        #If &&2<> '0'
                #Error 'Unpaired While'
        #End_If
    #End_If

    &&2= '0' | &&3=Pos

    W&&2: cmp #1 #3 | jn#2 W&&2>>]

[.End_While
    #If &&2<> '0'
        #ErrorPos  &&3 'Unpaired While'
    #End_If
    jmp W&&2<< | w&&2:
    &&2=0]

[While
    #If &&2=0
        &&2= '0'
    #Else
        &&2=&&2+1
    #End_If
    W&&2: cmp #1 #3 | jn#2 W&&2>>]

[End_While | jmp W&&2<< | w&&2:
             #If &&2= '0'
                &&2=0
             #Else
                &&2=&&2-1
             #End_If]
____________________________________________________________________________________________

[.Do
    #If &&4<>0
        #If &&4<> '0'
                #Error 'Unpaired Do'
        #End_If
    #End_If

    &&4= '0' | &&5=Pos

    D&&4:]

[.Loop_Until
    #If &&4<> '0'
        #ErrorPos  &&5 'Unpaired Do Until'
    #End_If

    cmp #1 #3 | jn#2 D&&4<<
    &&4=0]

[.Loop_While
    #If &&4<> '0'
        #ErrorPos  &&5 'Unpaired Do While'
    #End_If

    cmp #1 #3 | j#2 D&&4<<
    &&4=0]

[Do
    #If &&4= 0
        &&4= '0'
    #Else
        &&4=&&4+1
    #End_If

    D&&4: ]

[Loop_Until | cmp #1 #3 | jn#2 D&&4<<  | D&&4:
 #If &&4= '0'
    &&4=0
 #Else
    &&4=&&4-1
 #End_If]

[Loop_While | cmp #1 #3 | j#2 D&&4<<  | D&&4:
 #If &&4= '0'
    &&4=0
 #Else
    &&4=&&4-1
 #End_If]
____________________________________________________________________________________________

[.For
    #If &&6<>0
        #If &&6<> '0'
            #Error 'Unpaired For'
        #End_If
    #End_If
    &&6= '0' | &&7=Pos

    #If #3=imm
        mov #1 (#3-1)
    #Else
        mov #1 #3
        dec #1
    #EndIf
 F&&6:
    inc #1 | cmp #1 #5 | ja F&&6>> ]

[.Next | jmp F&&6<<
 F&&6:
    #If &&6<> '0'
        #ErrorPos &&7 'Unpaired For'
    #End_If
    &&6=0]

[For
    #If &&6=0
        &&6= '0'
    #Else
        &&6=&&6+1
    #EndIf

    #If #3=imm
        mov #1 (#3-1)
    #Else
        mov #1 #3
        dec #1
    #EndIf
 F&&6:
    inc #1 | cmp #1 #5 | ja F&&6>> ]


[Next | jmp F&&6<< | F&&6: &&6=&&6-1]

[Break | jmp F&&6>>]
[Continue | jmp F&&6<<]
[ExitF | jmp F0>>]
____________________________________________________________________________________________

;;
  &1 = Size of arguments 
  &2 = Size of local data (local+structures) 
  &3 = preserved regs 
;;

[Proc | &1=0 | &2=0 | &3= | #1 | push ebp | mov ebp esp]

[Arguments | {#1 ebp+((#x*4)+4)} | #+1 | &1=(#N*4)]

[Local | {#1 ebp-(#x*4)} | #+1 | &2=(#N*4) | sub esp &2]

[GetMember | {#3 ebp-(#F-#2)} | #+2]

[Structure | {#1 ebp-(&2+#2+4)} | sub esp #2 | push esp | GetMember &2+#2 #L>3 | &2=&2+#2+4]

[Uses | push #1>L | &3=pop #L>1]

[Return | #If #N=1 | mov eax #1 | #EndIf | jmp P9>>]

[ExitP | jmp P9>>]

[EndP | P9: | &3 | mov esp ebp | pop ebp | ret &1]

[.EndP | P9: | &3 | mov esp ebp | pop ebp | ret &1]
____________________________________________________________________________________________

[OFN_FILEMUSTEXIST 01000  OFN_PATHMUSTEXIST 0800     OFN_LONGNAMES 0200000
 OFN_EXPLORER 080000      OFN_HIDEREADONLY 04]

[OPEN_EXISTING 3   OPEN_ALWAYS 4  GENERIC_READ 080000000  GENERIC_WRITE 040000000
 FILE_SHARE_READ 1  FILE_SHARE_WRITE 2  FILE_ATTRIBUTE_ARCHIVE 20  CREATE_NEW 1
 GMEM_MOVEABLE 2  GMEM_ZEROINIT 040]




TITLE DllInit

[hInstance: 0]
[HbHeap: ?]

Proc Main:
    Arguments @Instance, @Reason, @Reserved

        move D$hInstance D@Instance

        .If D@Reason = &DLL_PROCESS_ATTACH
            ; ...
             push 00
             push 01000
             push 0
             call 'KERNEL32.HeapCreate'
             mov D$HbHeap eax

        Else_If D@Reason = &DLL_PROCESS_DETACH
            ; ...
            push D$HbHeap
            call 'KERNEL32.HeapDestroy'

        Else_If D@Reason = &DLL_THREAD_ATTACH
            ; ...

        Else_If D@Reason = &DLL_THREAD_DETACH
            ; ...

        .End_If

        mov eax &TRUE
Endp
align 010

____________________________________________________________________________________________
____________________________________________________________________________________________

TITLE HbMain

ORD01::'HB_Enter'

 push ebp
  mov ebp esp
  sub esp 010
  push ebx
  push esi
  push edi
  mov esi D$ebp+08
    call MainSw
  pop edi
  pop esi
  pop ebx
  mov esp ebp
  pop ebp
 ret
 align 010

_________________________________________________________________


[Sw1: 0, HbInit, SrvMain, ClnMain, SrvSw, ClnSw]

[procA: '?GM_MPDED_ReleaseStart@@YAHPAD@Z',0]
[<16 Data: D$ ? #01390]
[Sets: D$ ? #010]
[tmp: D$ ? #04B0]
[Gamedll: 'game.dll',0]
[GameBase: D$ 0]
[<16 MapInitPtr: D$ 0]
[IsCln: D$ 0]
[ClnTime: ?]

MainSw:
    mov edi esi
    mov eax D$edi
    test eax eax | je X1>
    cmp eax 5 | ja Y1>

     jmp D$eax*4+Sw1

Y1:
    cmp eax 064 | jne Y2>
    call InitCln
    jmp X1>
Y2:
    cmp eax 0CA | je SendInitmaps
    cmp eax 065 | jne X1>

;disconnect 065
   movzx eax B$edi+4
   xor ecx ecx
   cmp al 25 | ja X1>
   lea edx D$eax*8+Clients
   mov D$edx ecx | mov D$edx+4 ecx

X1:
 ret



HbInit:
    mov esi Sets
    mov eax D$edi+08
    mov D$esi+0C eax
    mov ecx D$edi+0C
    mov D$esi+04 ecx
    mov eax D$edi+020
    cmp eax 03E8 | je N6>
 ret

N6:
    mov edx D$edi+010
    mov D$esi+010 edx
    mov eax D$edi+014
    mov D$esi+014 eax
    mov ecx D$edi+018
    mov D$esi+018 ecx
    mov edx D$edi+01C
    mov D$esi+020 edx

    mov edx D$hInstance
    mov D$edi+04 edx

  call 'KERNEL32.GetModuleHandleA' Gamedll
   mov D$GameBase eax
   test eax eax | je E6>

  call 'KERNEL32.GetProcAddress',
            eax,          ; handle to DLL module
            procA         ; function name

    add eax 024B0
    mov D$MapInitPtr eax
E6:

 ret
align 010

__________________________________________________________________


[MaxSize: ?]
[Settingfile: "// Max filesize to directly send for players. exmpl. 15000000 = 15MB.
// Link can be max 58 characters long. %d.txt needs to be end of link.

MaxFilesize = 0
Link = vc2-map-addon-project.googlecode.com/svn/trunk/%d.txt
",0]

[Dwnldst: 'downloadsettings.ini',0]


ORD02::'SrvInit'
InitSrv:
 mov edi Dwnldst
 mov ecx edi
 call GetFileSize
 test eax eax | jne K8>
 call WriteDefSetting

K8:
  mov esi tmp
  ;1=file, 2buf, 3size, 4offset
  call ReadFileP edi, esi, 0124, 0

  xor ecx ecx
  mov D$MaxSize ecx
L9:
  cmp ecx 0124 | jnb F5>>
  mov eax D$esi+ecx
  inc ecx
  cmp eax "MaxF" | jne L9<
   cmp D$esi+ecx+3 "iles" | jne L9<
   lea esi D$ecx+esi+10
L1:
    mov al B$esi | inc esi | cmp al  "=" | jne L1<
L2:
    mov al B$esi | inc esi | cmp al  " " | jbe L2<
    dec esi
    cmp al "0" | je S4>
S3:
    call DecHex
     mov D$MaxSize eax
S4:
   xor ecx ecx
L7:
  cmp ecx 0124 | jnb F5>
  mov eax D$esi+ecx
  inc ecx
  cmp eax "Link" | jne L7<
   cmp W$esi+ecx+3 " =" | jne L7<
   lea esi D$ecx+esi+3
L1:
    mov al B$esi | inc esi | cmp al  "=" | jne L1<
L2:
    mov al B$esi | inc esi | cmp al  " " | jbe L2<
    dec esi
    mov edx SrvLink
    mov cl 03e
L5:
    mov al B$esi
    inc esi
    cmp al 0e | jb S6>
    dec cl | je S6>
    mov B$edx al
    inc edx | jmp L5<
S6:
    mov B$edx 0
F5:

ret
align 010


[NumberOfBytes3: ?,?]
WriteDefSetting:
    push edi
      call 'KERNEL32.CreateFileA' Dwnldst,
                            GENERIC_WRITE,             ; Opened for Read/write
                                        7,             ; Shared for
                                        0,             ; Security
                                        2,             ; for an existing or new file
                                      080,             ; File attribute normal
                                        0              ; hTemplateFile
    cmp eax 0-01 | je F1>
    mov edi eax

    call 'KERNEL32.WriteFile' edi, Settingfile, 226, NumberOfBytes3, 0
    call 'KERNEL32.CloseHandle' edi

F1:
pop edi
ret
align 010



DecHex:
 push esi
  movzx ecx B$esi
  inc esi | xor eax eax
 L1:
    cmp ecx 030 | jl K1>
    cmp ecx 039 | jg K1>
    sub ecx 030
    lea eax D$eax*4+eax
    lea eax D$eax*2+ecx
    movzx ecx B$esi
    inc esi | jmp L1<
 K1:
 pop esi
ret
align 010
_______________________________________________________________________________


[SrvLink: D$ ? #018]

InitCln:
  push esi,edi

    movzx edx B$edi+4
    cmp dl 25 | ja S1>
    mov B$edx*8+Clients dl
S1:

;link
    mov edi Data+4
    mov esi SrvLink
    mov eax edi
    mov ecx 0f
    rep movsd
    pop edi

    mov D$eax-4 02A9
    push 1
    push 044  ;size
    push Data ;ptr
    push edx  ;clnId
    mov ecx Sets
    call Send

 pop esi
ret
align 010

__________________________________________________________________


Send:
   sub esp 014
    push esi,edi
    mov edi D$esp+028 | mov esi ecx
    mov ecx D$esp+020 | mov edx D$esp+024
    mov eax D$esp+02C
    mov D$esp+0C ecx   ;id
    lea ecx D$esp+08
     push ecx
     mov D$esp+0C 0A
     mov D$esp+014 edi ;size
     mov D$esp+018 edx ;ptr
     mov D$esp+01C eax ;1
     call D$esi+0C
     add esp 04
  pop edi,esi
 add esp 014
ret 010
align 010


_________________________________________________________________

[FileHandle2: ?]
[NumberOfBytes2: ?,?]

;1=file, 2buf, 3size, 4offset
ReadFileP:
    push ebp | mov ebp esp
    push edi,esi
    sub esp 028
    mov eax D$ebp+8
     call 'KERNEL32.CreateFileA'      eax,
                             GENERIC_READ,             ; Opened for Read/write
                                        7,             ; Shared for
                                        0,             ; Security
                                        3,             ; for an existing or new file
                                      080,             ; File attribute normal
                                        0              ; hTemplateFile
    mov D$FileHandle2 eax
    cmp eax 0-01 | je F1>
    mov edi eax

    mov eax D$ebp+014
    test eax eax | je O1>


    call 'KERNEL32.SetFilePointer',
                               edi,        ; handle to file
                               eax,        ; bytes to move pointer
                                 0,        ; bytes to move pointer
                                 0
O1:
 mov esi NumberOfBytes2
 call 'KERNEL32.ReadFile' edi, D$ebp+0c, D$ebp+010, esi, 0
 call 'KERNEL32.CloseHandle' D$FileHandle2
 mov eax D$esi
F1:
  add esp 028
 pop esi,edi,ebp
ret 010
align 010


___________________________________________________________________

;ecx = file
GetFileSize:
  push edi,esi
      call 'KERNEL32.CreateFileA' ecx,
                             GENERIC_READ,             ; Opened for Read/write
                                        7,             ; Shared for
                                        0,             ; Security
                                        3,             ; for an existing or new file
                                      080,             ; File attribute normal
                                        0              ; hTemplateFile

    cmp eax 0-01 | je F5>
    mov edi eax

      call 'KERNEL32.GetFileSize',
       edi,
       0

    mov esi eax
    call 'KERNEL32.CloseHandle' edi
    mov eax esi
D3:
 pop esi,edi
ret
F5:
 xor eax eax | jmp D3<
align 010

_________________________________________________________________





TITLE Maplist

[<4 NumberOfBytes: D$ 0,0]
[<4 FileHandle: D$ ?]
[<16 Maplist: D$ ? #0498]
[<16 MaplistPs: D$ ? #0F8]
[Fail: D$ 0]
[SrvFile: 'Latest.srv',0]
[MapFile: 'maps\initlog.txt',0]
[MapIdListS: D$ ?]
[MapIdListS2: D$ ?]
[MapCnt: D$ ?]

ORD03::'Do_maplist'
InitMaplist:
    push edi,esi,ebx,ebp
    sub esp 060
    call InitSrv
     cmp D$MaxSize 0100 | jb F33

    xor ebx ebx

 call ReadFile SrvFile
 test eax eax | je N1>>

  xor edi edi
  mov D$esp+020 eax
  mov D$esp+024 ecx
   mov esi eax | mov ebp ecx | mov ebx tmp
L1:
    mov eax D$esi
     dec ecx | je R1>
      inc esi
       cmp eax "map " | jne L1<
       cmp B$esi-02 " " | ja L1<
        cmp B$ esi+03 "=" | jne L1<
         add esi 4
          sub ecx 4
         jmp L3>
L2:
    inc ebx
L3:
    dec ecx | je R1>
     inc esi | mov al B$esi
      cmp al "9" | ja L1<
       test al al | je R1>
        cmp al "," | mov B$ebx al
         jne L2<
          inc ebx | inc edi | jmp L1<
R1:
    mov D$MapIdListS edi
     call 'KERNEL32.HeapFree' D$HbHeap, 0, D$esp+020

     test edi edi | je N1>
;check customs in srvlist
F1:
     call ReadFile MapFile
      test eax eax | je N1>
       mov D$esp+020 eax | mov D$esp+024 ecx

     call DoList edi, ecx, eax
     call 'KERNEL32.HeapFree' D$HbHeap, 0, D$esp+020
N1:
;check all maps from init.txt
     call ReadFile MapFile
      test eax eax | je F2>
        mov D$esp+020 eax | mov D$esp+024 ecx

     call DoListAll ecx, eax
     call 'KERNEL32.HeapFree' D$HbHeap, 0, D$esp+020

     call Sort

  mov eax D$MapIdListS
  add eax D$MapIdListS2
  mov D$MapCnt eax


jmp K4>
F2:
  cmp D$Ptrs 0 | jne K4>
F33:
  mov D$Fail 1
K4:
   add esp 060
   pop ebp,ebx,esi,edi
   ret
   align 010





;ebp+ 8=mem, +c=size +10=count
DoList:
  push ebp | mov ebp esp
  sub esp 050
  xor edx edx
  mov ebx D$ebp+08
   mov esi tmp | xor ecx ecx
L7:
   lea edi D$esp+8
L8:
    mov al B$esi | cmp al "," | je G1>
    mov B$edi+edx al | inc edx
     inc esi | cmp edx 022 | jb L8<
     jmp I2>
G1:
      lea edi D$esp+8
      push D$ebp+010, D$ebp+0c, edi, edx
      call GetDstr
I2:
       inc esi
       xor edx edx
  dec ebx | jne L7<


M1:
 add esp 050
 pop ebp
ret 0c
align 010



[ptrp: ?]
[ptrs: ?]

;esp+ 14=stringlen, +18=string +1c=size +20=mem
GetDstr:
 push edi,ecx,esi,ebx
  mov edi D$esp+020
  mov ecx D$esp+014
  mov esi D$esp+018
  xor eax eax
  push ebp
  xor edx edx
  mov ebp D$esp+020
jmp A1>

L1:
    inc eax | inc edx | cmp eax ecx | je L2>
A1:
     mov bl B$edi+edx
     cmp bl B$esi+eax | je L1<
     xor eax eax
D1:
     inc edx
     cmp edx ebp | jb A1<
    jmp E6>

L2:
   xor esi esi
   add edi edx
 jmp L3>
J1:
   inc esi | cmp esi ebp | jnb E6>
L3:
   mov al B$edi | cmp al "]" | jne J1<
    add edi 3
     mov esi Maplist | mov edx MaplistPs
      add esi D$Ptrs | add edx D$Ptrp
    xor ecx ecx | jmp S5>
L6:
    mov B$esi+ecx al | inc ecx
S5:
    mov al B$edi+ecx | cmp al " " | jnb L6<
     mov D$edx esi | add D$Ptrp 4
     add ecx 2 | add D$Ptrs ecx

E6:
  pop ebp,ebx,esi,ecx,edi
 ret 010
 align 010




ReadFile:
    mov eax D$esp+04
    push edi,ebp,esi
    sub esp 028
     call 'KERNEL32.CreateFileA' eax,
                             GENERIC_READ,             ; Opened for Read/write
                                        7,             ; Shared for
                                        0,             ; Security
                                        3,             ; for an existing or new file
                                      080,             ; File attribute normal
                                        0              ; hTemplateFile
    mov D$FileHandle eax
    cmp eax 0-01 | je F1>
    mov edi eax

      call 'KERNEL32.GetFileSize',
       edi,
       0

      mov esi eax
      add eax 8
      call 'KERNEL32.HeapAlloc' D$HbHeap, 0, eax
      mov ebp eax

 call 'KERNEL32.ReadFile' edi, ebp, esi, NumberOfBytes, 0
 call 'KERNEL32.CloseHandle' D$FileHandle
 mov eax ebp | mov ecx esi
 jmp D1>
F1:
   xor eax eax | jmp D1>
D1:
 add esp 028
 pop esi,ebp,edi
ret 4
align 010




DoListAll:
  push ebp
;  mov ecx D$MapIdListS
  mov ebp D$esp+08
  mov ebx ebp
  mov edi D$esp+0c
  add ebp edi
 jmp L5>

C1:
 inc edi
  L5:
    mov eax D$edi
     cmp edi ebp | jnb E7>
      cmp eax "maps" | jne C1<
 cmp B$edi+4 "\" | jne C1<



   xor esi esi
     mov esi Maplist | mov edx MaplistPs
      add esi D$Ptrs | add edx D$Ptrp
    xor ecx ecx | jmp S5>
L6:
    mov B$esi+ecx al | inc ecx
S5:
    mov al B$edi+ecx | cmp al " " | jnb L6<
     mov D$edx esi | add D$Ptrp 4
     add ecx 2 | add D$Ptrs ecx | add edi 6
      mov eax D$MapIdListS2 | inc eax
      cmp eax 118 | mov D$MapIdListS2 eax
    jnb E7>
 cmp edi ebp | jb L5<

 E7:
 pop ebp
ret 8
align 010


___________________________________________________________________________



Sort:
 sub esp 0c
 mov ebp tmp
 mov ecx 080
 mov ebx D$MapIdListS2
 mov edi ebp
 xor eax eax
 rep stosd
 mov edi D$MapIdListS

  lea edi D$edi*4+MaplistPs
K2:
   mov ecx D$edi
   test ecx ecx | je N6>
    call GetFileSize
    test eax eax | je N6>
    mov ecx D$edi
    lea edx D$ebx*8+ebp
    mov D$edx eax
    mov D$edx+4 ecx
N6:
    add edi 4
    dec ebx | jne K2<

 mov edi D$MapIdListS
  mov ebx D$MapIdListS2

  mov D$esp+04 edi
  lea edi D$edi*4+MaplistPs
  xorps xmm4 xmm4
 mov ebp tmp
M6:
 mov edx D$MapIdListS2
 mov esi D$ebx*8+ebp+4

  mov eax D$ebx*8+ebp
F3:
   test eax eax | je H9>

     mov ecx D$edx*8+ebp
     test ecx ecx | je H9>
      cmp eax ecx | jb H9>
       mov esi D$edx*8+ebp+4
       mov D$esp+08 edx
       mov eax ecx
H9:
       dec edx
       jne F3<

    mov D$edi esi
    add edi 4
      mov edx D$esp+8
       lea edx D$edx*8+ebp
       movlps X$edx xmm4
B1:
       movlps xmm0 X$edx+8
       movlps X$edx xmm0
       add edx 8
       comiss xmm0 xmm4 | jne B1<
    dec ebx | jne M6<

S5:
 add esp 0c
ret
align 010



TITLE Downloads

[<16 Clients: D$ ? #0F8]
[Tm2: D$ 0]
;check clns and send map
;Clients dwords: [id, 1, 2, 0][4,]   1=downloading, 2=mapId, 4=pingtime
;(1) 0 checkingmaps, 1 downloading, 2 all maps loaded.

ORD04::'Check_clns_maps'

DownldChecClns:

 cmp D$Fail 0 | je X1>
  ret
X1:
  fld F$time
  fadd F$Tm2
  fld1
  fcomip st0 st1 | fstp F$Tm2
  jb S8>
 ret
S8:
 mov D$Tm2 0
 push edi,esi,ebx
 sub esp 060


mov ecx 25 ;max downloaders +10
 mov edi Clients
L1:
  mov al B$edi
   test al al | jne D1>
L4:
   add edi 8
    dec ecx | jne L1<
   jmp E2>>
D1:
   mov al B$edi+1
;   cmp al 2 | je L4< ;all maps loaded
   test al al | jne L4<

;start download
 mov esi MaplistPs
  xor eax eax
  mov ecx D$MapCnt
  mov al B$edi+2 ;map id
  cmp al cl | jnb D9>

  lea eax D$eax*4+esi ;get map >id
   xor ebx ebx | mov edx D$eax
    test edx edx | je D9>
    mov ecx Data+8
H4:
  mov al B$edx+ebx
     mov B$ecx+ebx al
      inc ebx
     cmp ebx 030 | ja E3>
 test al al | jne H4<

      mov B$edi+01 1
      add ebx 9

      mov ecx edx
      call GetFileSize
      test eax eax | je E3>
      cmp eax D$MaxSize | ja E5> ;max size
      mov D$Data+4 eax

;send
    mov D$Data 02A6
     movzx eax B$edi
    push 01
    push ebx  ;size
    push Data ;data
    push eax  ;clnId
    mov ecx Sets
    call Send


E2:
  add esp 060
  pop ebx,esi,edi
 ret

D9:
    mov B$edi+1 2
    jmp E2<
E5:
    mov B$edi+1 0
E3:
    inc B$edi+2
    jmp E2<
    align 010







TITLE AskData

[Done: ?]
[<4 FailCnt: ?]
[Hangtime: F$ 32]
[Tm3: ?]

; cln: [02a2] [datasize] [offset] [time] [filename]
ORD0A::'AskData'

AskData:
 cmp D$Done 0 | je R7>
 ret
R7:
 cmp D$FailCnt 12 | jbe T1>
    mov D$Data 02A1
    mov D$Data+4 1
    push 01
    push 08 ;datasize
    push Data
    mov ecx Sets
    call ClnSend
    call 'KERNEL32.DeleteFileA',
                        TmpFile
    test eax eax | jne T1>
    mov D$Done 1
T1:
 fld F$ClnTime
   fsub F$Hang
   fld F$Hangtime
   fcomip st0 st1 | fstp st0
   ja W2>
    mov D$Loading 1
W2:
  cmp D$loading 0 | jne G1>
 ret

G1:
 push ebp,esi
 sub esp 08
    mov D$Tm3 0

    mov ecx tmpFilename
    call GetFileSize
    mov ebp eax

    xor ecx ecx
    mov esi Data+010
F1:
    mov edx Filename
    mov al B$edx+ecx
    mov B$esi+ecx al
    inc ecx | cmp ecx 030 | jnb E1>
    test al al | jne F1<
    mov B$esi+ecx+01 al

    mov D$Data 02A2
    mov eax D$SendSize
    mov D$Data+4 eax ;datasize
    mov D$Data+8 ebp ;offset
    fld F$Clntime
    fstp F$Data+0c ;time

    add ecx 010

    push 01
    push ecx ;datasize
    push Data
    mov ecx Sets
    call ClnSend
    mov D$Loading 0
    inc D$FailCnt
D2:
 add esp 08
 pop esi,ebp
 ret
E1:
  inc D$FailCnt
  call ReadFileP TmpFile FileName 030 4
jmp D2<
 align 010




ClnSend:
    sub esp 014
    push esi
    push edi
    mov edi D$esp+024
    mov esi ecx
    mov ecx D$esp+020
    mov edx D$esp+028
    lea eax D$esp+08
    push eax
    mov D$esp+0C 0B
    mov D$esp+010 edi
    mov D$esp+014 ecx
    mov D$esp+018 edx
    call D$esi+0C
    add esp 04
    pop edi
    pop esi
    add esp 014
    ret 0C
    align 010
TITLE Server

[Maps: ?]
[Time: ?]

ORD0D::'Srv'
SrvMain:

 movss xmm0 X$edi+4
  addss xmm0 X$time
  movss X$Time xmm0

 cmp D$Maps 0 | jne S3>
  call InitMaplist
   mov D$Maps 1
S3:
  call DownldChecClns
ret
align 010





;SERVER RECEIVE
;2a1=check cln answ, 2a2=
SrvSw:
 mov esi D$edi+0c
 mov eax D$esi | cmp eax 02A0 | jb S9>

 sub eax 02A1 | je C1>
 cmp eax 1 | jne S9>
C2:
;2A2
   call SendData
   jmp S9>
C1:
;2A1
   call CheckAnswer

S9:
  ret
  align 010


;esi = data
;edi+4 id
;edi+8 size
;;
already have map = 01
no have map = 077
previous download in progress = 044
;;

;Clients dwords: [id, 1, 2, 0][4,]   1=downloading, 2=mapId, 4=pingtime
;(1) 0 checkingmaps, 1 downloading, 2 all maps loaded.

CheckAnswer:
 movzx eax B$edi+04
 lea edx D$eax*8+Clients
 cmp al B$edx | jne E1>

 push edi,esi
  mov eax D$esi+4
  cmp eax 1 | je N8>
  cmp eax 077 | je S4>
  cmp eax 044 | jne E1>
   mov B$edx+1 1 ;set cln downloadmode

E1:
 pop esi,edi
 ret


N8: ;1
 cmp B$edx+1 2 | je E0>
 mov al B$MapCnt
  mov cl B$edx+2 ;map id
  mov B$edx+1 0
   cmp cl al | jbe J2>
    mov B$edx+1 2 ;have all
J2:
   inc cl | mov B$edx+02 cl
E0:
 pop esi,edi
 ret


; 77 start load
S4:
 mov B$edx+1 1
 pop esi,edi
 ret
align 010

_________________________________________________



SendInitmaps:
  mov esi Data
    mov ecx D$edi+0c
    mov D$esi 02A8
    mov D$esi+04 ecx
    movzx eax B$edi+8
    push 1
    push 8  ;size
    push Data ;ptr
    push eax  ;clnId
    mov ecx Sets
    call Send
 ret
align 010




_________________________________________________
; cln: [02a2] [datasize] [offset] [time] [filename]

; srv: [02A7] [F$time] [checksum>] [size]
;      [offset] [done,1/0] [mapdata>size]

ORD09::'SendData'

SendData:
cmp D$MaxSize 0800 | jnb D4>
ret
D4:
 push ebp,ebx,esi,edi
 sub esp 020

 movzx eax B$edi+4
 lea ecx D$eax*8+Clients
 cmp B$ecx+1 2 | je F6>>

 mov ebp D$esi+4   ;size
 mov eax D$esi+08  ;offset
 fld F$esi+0c      ;time
 fstp F$esp+8
 lea ecx D$esi+010 ;file
  mov D$esp+4 eax
  cmp ebp 11000 | jnb F6>> ;max size
  mov esi Data
  lea edx D$esi+018 ;buf
 ;1=file, 2buf, 3size, 4offset
  call ReadFileP ecx, edx, ebp, eax
  cmp eax 0-01 | je F6>

Y6:
  mov D$eax+esi+018 0
  xor ecx ecx
  mov ebx eax
  cmp eax ebp | jnb N3>
  inc ecx            ;finish
N3:
   lea ebp D$esi+010 ;x+3
   fld F$esp+8
   mov D$esi+014 ecx
   mov ecx D$esp+4
   mov D$esi+010 ecx ;offset
   fstp F$esi+4
   mov D$esi+0c ebx  ;siz
   xor edx edx

   shr eax 2 | inc eax
L3:
   add edx D$eax*4+ebp
   dec eax | jns L3<
   mov D$esi+8 edx ;checksum

   add ebx 01c

    mov D$esi 02A7
    movzx eax B$edi+4
    push 01
    push ebx  ;size
    push Data ;ptr
    push eax  ;clnId
    mov ecx Sets
    call Send

  mov eax D$esi+014
   test eax eax | je F6>
   call AddTxt

F6:
 add esp 020
 pop edi,esi,ebx,ebp
ret
align 010



[Ctxt: 'Cln %d finished download: %s',0]

AddTxt:
 sub esp 070
 mov eax D$edi+0c
 lea edx D$eax+010
 lea ecx D$esp+020
 push edx, D$edi+4, Ctxt, ecx
 call 'msvcrt.sprintf'

   push 01
   lea edx D$esp+034
   push edx
   mov ecx Sets
   call SendTxt

 add esp 080
ret
align 010



SendTxt:
    sub esp 0C
    mov eax D$esp+010
    mov edx D$esp+014
    mov D$esp+04 eax
    lea eax D$esp
    push eax
    mov D$esp+04 020
    mov D$esp+0C edx
    call D$ecx+0C
    add esp 010
    ret 08
    align 010

















TITLE Cln
ORD0E::'Cln'


[DlEnabled: ?]
ClnMain:

    mov D$IsCln 1
    movss xmm0 X$edi+4
     addss xmm0 X$ClnTime
     movss X$ClnTime xmm0

   cmp D$DlEnabled 0 | je V1>
    call AskData
V1:
ret
align 010



;CLN RECEIVE
ClnSw:
 mov eax D$edi+0c
 mov ecx D$eax
 cmp ecx 02A0 | jb S9>

 sub ecx 02a6 | je S1>
  cmp ecx 1 | je R1>
  cmp ecx 2 | je R2>
  cmp ecx 3 | je R3>
 jmp S9>

S1:
   call HaveMap
 jmp S9>

R1:
   push esi
   mov esi eax
   call ReceiveData
   pop esi
 jmp S9>
R2:
   mov ecx D$eax+4
   test ecx ecx | jne S9>
   cmp D$IsCln 1 | jne S9>
   call Initmaps
 jmp S9>
R3:
   push esi
   mov esi eax
   call ReceiveLink
   pop esi
S9:

  ret
  align 010




[Loading: D$ 0]
[TmpFile: 'maps\downloading\download.bin',0]
[tmpFilename: 'maps\downloading\', D$ 0 #024]
;;
eax = data, (eax=esi+0c)
esi+08 size

answers:
already have map = 01
no have map = 077
previous download in progress = 044
;;

HaveMap:
 push ebp
 push esi,edi
 sub esp 060
 mov esi eax
 mov D$FailCnt 0

    mov ecx Tmpfile
    call GetFileSize
    test eax eax | je S6> ;no dwnl file
    lea ecx D$esi+08
    call GetFileSize
    test eax eax | jne Z1>
    mov edi 044 | jmp K4>

S6:
    lea ecx D$esi+08
    call GetFileSize
    test eax eax
    mov edi 077 | je K2> ;no have map
Z1:
    call 'KERNEL32.DeleteFileA' Tmpfile
    mov edi 1            ;have map
    jmp K1>
K2:
    lea ecx D$esi+4
    call DoDwnload
    mov edi 044
K4:
    call ReadFileP TmpFile FileName 030 4 ;tmpfile=download info
    mov D$DlEnabled 1
    call DoTmpfilename
    mov D$Loading 1

K1:
    mov D$Data 02A1
    mov D$Data+4 edi

    push 01
    push 08 ;datasize
    push Data
    mov ecx Sets
    call ClnSend

D1:
 add esp 060
 pop edi,esi
 pop ebp
ret
align 010


[<4 Filename: D$ ? #030]
[SendSize: D$ 10240] ;20k max

;recv data Dwords [02A7] [F$time] [checksum>] [size]
;                 [offset] [done,1/0] [mapdata>size]
;done 1 done

ORD06::'Recv_data'

ReceiveData:
push edi,ebx
  sub esp 020
  mov D$Loading 1
  mov D$FailCnt 0

   movss xmm0 X$esi+04
   call TuneSpeed

   mov ecx tmpFilename
   call GetFileSize
   cmp eax D$esi+010 | jne E7>

   mov ecx D$esi+0c             ;size
   cmp ecx 11000 | ja E7>       ;data err
   xor edi edi
   lea edx D$esi+010 ;x+3
   xor eax eax
    shr ecx 2 | inc ecx
L5:
   add edi D$ecx*4+edx
   dec ecx | jns L5<
   cmp edi D$esi+08 | jne E7>   ;data err

   mov ecx D$esi+010 ;offset
   call Write ecx
    cmp D$esi+014 0 | je K99
    call Finalize
    mov D$Loading 0

;get next
    mov D$Data 02A1
    mov D$Data+4 1
    push 01
    push 08 ;datasize
    push Data
    mov ecx Sets
    call ClnSend
  jmp F3>


E7: ;ask re send
; cln: [02a2] [datasize] [offset] [time] [filename]
   mov ebx Filename
   mov ecx tmpFilename
   call GetFileSize
    mov D$Data 02A2
    mov D$Data+8 eax   ;offs
    mov edx D$Sendsize ;size
    mov D$Data+4 edx
    xor ecx ecx
L8:
    mov al B$ebx+ecx
    mov B$ecx+Data+010 al
    inc ecx
    test al al | jne L8<

    fld F$Clntime
    fstp F$Data+0c  ;time

    add ecx 010

    push 01
    push ecx ;datasize
    push Data
    mov ecx Sets
    call ClnSend
F3:

K99:
   add esp 020
  pop ebx,edi
ret
align 010


__________________________________________________

[Hang: F$ 0]
[TH: F$ 1000]
ORD0B::'TuneSpeed'

TuneSpeed:

  movss xmm3 X$Clntime
  movss X$Hang xmm3
  subss xmm3 xmm0
  mulss xmm3 X$TH
  cvtss2si eax xmm3
  mov ecx SendSize

  cmp eax 400 | jnb B1>
  cmp eax 100 | jb B2>
  cmp eax 330 | jnb B3>
  cmp eax 165 | jb B4>
  cmp eax 228 | jb B5>

  mov D$ecx 1520  ;4
ret
B5:
  mov D$ecx 2960  ;3
ret
B4:
  mov D$ecx 5840  ;2
ret
B3:
  mov D$ecx 1280  ;5
ret
B2:
  mov D$ecx 10240 ;1
ret
B1:
   mov D$ecx 880 ;6
ret
align 010

______________________________________________________

DoTmpFilename:

   mov ecx Filename+5
   mov edx tmpFilename+17
L4:
    mov al B$ecx
    mov B$edx al
    inc ecx | inc edx
    test al al | jne L4<
ret
align 010

______________________________________________________

[Link: D$ ? #018]

ReceiveLink:
  lea ecx D$esi+04
  xor edx edx
L5:
   mov al B$ecx+edx
   mov B$Link+edx al
   test al al | je D4>
   inc edx | cmp edx 60 | jb L5<
D4:
  call SetNewHttpAdr
ret
align 010


___________________________________________________


[OldPrtc: ?]
[pHandle: ?]

SetNewHttpAdr:
   push ebp

    mov ebp D$GameBase
     test ebp ebp | je E1>
     cmp D$ebp+087AFB0 0 | jne E1>

call 'KERNEL32.GetCurrentProcessId'
call 'KERNEL32.OpenProcess',
     08,         ; access flag
     0,          ; handle inheritance option
     eax         ; process identifier

     test eax eax | mov D$pHandle eax | je E1>

      ;add ebp 02560C4
      add ebp 0A7930


        call 'KERNEL32.VirtualProtectEx',
             eax,                     ; handle to process
             ebp,                     ; region of committed pages
             020,                     ; size of region
             4,                       ; desired access protection
             OldPrtc                  ; old protection

        call 'KERNEL32.CloseHandle' D$pHandle

     add D$ebp+1 0624EEC
     mov ebp D$ebp+1
     mov edx Link ;Addr

       xor ecx ecx
L8:
       mov al B$edx+ecx
       mov B$ecx+ebp al | test al al | je E1>
       inc ecx | cmp ecx 60 | jb L8<
E1:
   pop ebp
  ret
  align 010

_________________________________________________________



DoDwnload:
  push edi,esi
  mov esi ecx
    sub esp 028
    mov edi TmpFile
     call CreateDirForFile edi
     call 'KERNEL32.CreateFileA'      edi,
                            GENERIC_WRITE,             ; Opened for Read/write
                                        7,             ; Shared for
                                        0,             ; Security
                                        2,             ; for an existing or new file
                                      080,             ; File attribute normal
                                        0              ; hTemplateFile
    mov D$FileHandle2 eax
    cmp eax 0-01 | je F7>
    mov edi eax

 call 'KERNEL32.WriteFile' edi, esi, 030, NumberOfBytes3, 0
 call 'KERNEL32.CloseHandle' D$FileHandle2
F7:
  add esp 028
 pop esi,edi
ret
align 010





ORD08::'Write'

Write:
    push edi
    mov eax tmpFilename
      call 'KERNEL32.CreateFileA'     eax,
                            GENERIC_WRITE,             ; Opened for Read/write
                                        7,             ; Shared for
                                        0,             ; Security
                                        4,             ; for an existing or new file
                                      080,             ; File attribute normal
                                        0              ; hTemplateFile
    mov D$FileHandle2 eax
    cmp eax 0-01 | je F1>
    mov edi eax
    mov ecx D$esp+8
    test ecx ecx | je V2>

    call 'KERNEL32.SetFilePointer',
                               edi,        ; handle to file
                               ecx,        ; bytes to move pointer
                                 0,        ; bytes to move pointer
                                 0         ; starting point

V2:
    mov eax D$esi+0c  ;size
    lea ecx D$esi+018 ;received data
    call 'KERNEL32.WriteFile' edi, ecx, eax, NumberOfBytes3, 0
    call 'KERNEL32.CloseHandle' D$FileHandle2

F1:
pop edi
ret 4
align 010



[Stuff: D$ ? #0c]


Finalize:
 push edi,esi
 sub esp 020
 mov edi tmpFilename
 mov esi Filename

 call ReadFileP edi Stuff 4 8
 mov ecx edi
 call GetFileSize
 cmp eax D$Stuff | je S6>

  call 'KERNEL32.DeleteFileA',
                          edi
 jmp S7>

S6:
  call 'KERNEL32.MoveFileA',
                        edi,         ; file name
                        esi          ; new file name
S7:
  call 'KERNEL32.DeleteFileA',
                      TmpFile        ; file name
  call 'KERNEL32.Sleep' 2

 add esp 020
 pop esi,edi
ret
align 010





CreateDirForFile:
    mov eax D$esp+04
    lea edx D$esp+0FFFFFF00
    sub esp 0100
    sub edx eax
F1:
    mov cl B$eax
    mov B$edx+eax cl
    inc eax
    test cl cl | jne F1<
    lea eax D$esp
    lea edx D$eax+01
G7:
    mov cl B$eax
    inc eax
    test cl cl | jne G7<
    sub eax edx | je I8>
    mov cl 05C
I0:
    cmp B$esp+eax cl | je K9>
    dec eax | jne I0<
I8:
    lea eax D$esp
    push eax
    mov B$esp+04 0
    call Code0100ECCC0
    add esp 0104
    ret 4

K9:
    mov B$esp+eax 0
    lea eax D$esp
    push eax
    call Code0100ECCC0
    add esp 0104
    ret 4
    align 010

Code0100ECCC0: J6:
    sub esp 0100
    push ebx
    mov ebx 'KERNEL32.CreateDirectoryA'
    push esi
    push edi
    mov edi D$esp+0110
    xor esi esi
M0:
    mov al B$esi+edi
    test al al
    lea ecx D$esi+edi | je P2>
    lea edx D$esp+0C
    sub edx edi
N6:
    cmp al 05C | je P2>
    mov B$edx+ecx al
    mov al B$ecx+01
    inc esi
    inc ecx
    test al al | jne N6<
P2:
    push 00
    lea eax D$esp+010
    push eax
    mov B$esp+esi+014 0
    call ebx
    cmp B$esi+edi 05C | jne C0>
    mov B$esp+esi+0C 05C
    inc esi
jmp M0<
C0:
    pop edi
    pop esi
    pop ebx
    add esp 0100
    ret
    Align 010


InitMaps:
 mov eax D$MapInitPtr
 test eax eax | je T1>
 call eax 1
 add esp 04
T1:
 ret
 align 010


